package org.csu.mybigpro.service;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.annotation.PostConstruct;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;


import java.util.*;

@Service
public class AiService {

    // 1. 从 application.properties 读取您的 Google AI API Key
    @Value("${google.api.key}")
    private String apiKey;

    @Autowired
    private RestTemplate restTemplate; // 直接注入共享的、带代理的RestTemplate

    private String aiApiUrl;
    private final ObjectMapper objectMapper = new ObjectMapper();

    @PostConstruct
    public void init() {
        // 构造带有API Key的URL
        this.aiApiUrl = "https://generativelanguage.googleapis.com/v1beta/models/gemini-1.5-flash-latest:generateContent?key=" + this.apiKey;
    }

    /**
     * 【新方法】: 根据用户描述生成试卷
     * @param description 用户提供的试卷要求
     * @return 包含试题的JSON字符串
     */
    public String generateExamFromDescription(String description) {
        String prompt = "你是一个专业的出题AI。请根据用户的描述，生成一份完整的试卷。你的任务是返回一个严格的JSON对象，该对象包含 'title' (试卷标题, String) 和 'questions' (一个JSON数组)。" +
                "数组中的每个问题对象都必须包含以下字段: 'topic'(知识点, String), 'type'('multiple-choice' 或 'true-false'), 'question'(题干, String), 'options'(一个Map，仅对选择题存在, key为'A','B','C'等, value为选项内容), 'answer'(标准答案, String)。\n" +
                "【用户要求】:\n" + description;
        return callAiApi(prompt);
    }


    /**
     * 【为文档解析新增的专属方法】: 从干净的、可能较长的文档题目文本中，提炼核心知识点作为关键词。
     * @param documentQuestionText 从Word文档中拆分出的单个题目全文
     * @return 包含多个搜索关键词的JSON数组字符串
     */
    public String generateSearchQueriesFromDocumentText(String documentQuestionText) {
        String prompt = "你是一个AI教学助手，任务是从一道完整的题目描述中，提炼出3个核心的、用于网络搜索的“知识点”或“解题方法”。\n\n" +
                "输入是一段从Word文档中提取的、格式清晰的题目文本。\n\n" +
                "--- 范例 ---\n" +
                "输入: \"已知等差数列{an}中，S₂ = -1, S₄ = 6, 则 a₅ 等于多少？ A. 27/2 B. 17/2 C. 13/2 D. 11/2\"\n" +
                "输出: [\"等差数列前n项和公式\", \"等差数列通项公式\", \"数列基本性质\"]\n\n" +
                "--- 现在，请处理以下输入 ---\n" +
                "输入: \"" + documentQuestionText + "\"\n" +
                "输出:";

        return callAiApi(prompt);
    }


    /**
     * 【核心方法】通用的内容生成方法，支持历史记录和工具
     * @param contents 对话历史
     * @param tools 可用工具
     * @param systemInstruction 系统指令
     * @return AI的原始响应JSON字符串
     */
    public String generateContent(List<Map<String, Object>> contents, List<Map<String, Object>> tools, String systemInstruction) {
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);

        Map<String, Object> requestBody = new HashMap<>();
        requestBody.put("contents", contents);

        if (tools != null && !tools.isEmpty()) {
            requestBody.put("tools", tools);
        }
        if (systemInstruction != null && !systemInstruction.isEmpty()) {
            requestBody.put("systemInstruction", Map.of("parts", List.of(Map.of("text", systemInstruction))));
        }

        HttpEntity<Map<String, Object>> entity = new HttpEntity<>(requestBody, headers);
        return restTemplate.postForObject(aiApiUrl, entity, String.class);
    }
    /**
     * 【已优化Prompt】
     * 明确指示AI如何处理位于文末的"参考答案"部分。
     */
    public String extractQuestionsFromText(String examText) {
        String prompt = "你是一个专业的试卷分析AI。这是从一个Word文档中提取的文本，里面包含带知识点标签的选择题和判断题。你的任务是解析这些文本，并以严格的JSON格式返回每一道题。JSON数组中每个对象应包含以下字段: 'id'(题号, 整数), 'topic'(知识点, 字符串, 如果没有请设为'常规'), 'type'('multiple-choice'或'true-false'), 'question'(题干), 'options'(一个Map，仅对选择题存在), 'answer'(标准答案)。\n" +
                "【重要指令】: 文档的末尾可能有一个'参考答案'区域，里面的答案是按顺序排列的。你必须将第N个答案正确地匹配给第N个问题。例如，答案区的第一行'C'对应第1题，第二行'B'对应第2题。\n\n" +
                "文本如下：\n" + examText;
        return callAiApi(prompt);
    }


    public String generateAnalysisReport(String analysisData) {
        // 【已优化Prompt】移除了让AI计算accuracyByTopic的要求，让AI专注于文字分析
        String prompt = "你是一位顶级的教育分析专家。一名学生完成了测试，这是他的答题情况和试题信息（JSON格式）。请为该学生生成一份详细的个人能力文字报告。报告应包含: 'strengths'(优势分析，字符串数组), 'weaknesses'(薄弱环节分析，字符串数组), 'suggestions'(学习建议，字符串数组)。请将完整的报告以严格的JSON格式返回。\n\n" +
                "数据如下：\n" + analysisData;
        return callAiApi(prompt);
    }
    /**
     * 【新方法1】: 发送带有工具定义的用户问题 (此方法保持不变)
     */
    public String callAiWithTools(String prompt, List<Map<String, Object>> tools) {
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);
        Map<String, Object> textPart = new HashMap<>();
        textPart.put("text", prompt);
        Map<String, Object> content = new HashMap<>();
        content.put("parts", Collections.singletonList(textPart));
        Map<String, Object> requestBody = new HashMap<>();
        requestBody.put("contents", Collections.singletonList(content));
        requestBody.put("tools", tools);
        HttpEntity<Map<String, Object>> entity = new HttpEntity<>(requestBody, headers);
        return restTemplate.postForObject(aiApiUrl, entity, String.class);
    }

    /**
     * 【核心改动】: 此方法现在接收完整的对话历史，并正确构造请求
     */
    public String callAiWithToolResult(List<Map<String, Object>> conversationHistory, String functionName, Object toolResult) throws Exception {
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);

        // 构造函数执行结果的部分
        Map<String, Object> functionResponsePart = Map.of("functionResponse", Map.of("name", functionName, "response", Map.of("content", toolResult)));

        // 【重要】根据Google API规范，角色必须是 "function"
        Map<String, Object> functionResultContent = Map.of("role", "function", "parts", Collections.singletonList(functionResponsePart));

        // 将函数执行结果追加到对话历史中
        List<Map<String, Object>> fullConversation = new ArrayList<>(conversationHistory);
        fullConversation.add(functionResultContent);

        Map<String, Object> requestBody = new HashMap<>();
        requestBody.put("contents", fullConversation); // 发送完整的历史记录

        HttpEntity<Map<String, Object>> entity = new HttpEntity<>(requestBody, headers);
        String rawResponse = restTemplate.postForObject(aiApiUrl, entity, String.class);

        // 解析最终的文本回复
        JsonNode rootNode = objectMapper.readTree(rawResponse);
        return rootNode.path("candidates").path(0).path("content").path("parts").path(0).path("text").asText("抱歉，我无法处理这个请求。");
    }
    private String callAiApi(String prompt) {
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);

        Map<String, Object> textPart = new HashMap<>();
        textPart.put("text", prompt);
        Map<String, Object> content = new HashMap<>();
        content.put("parts", Collections.singletonList(textPart));
        Map<String, Object> requestBody = new HashMap<>();
        requestBody.put("contents", Collections.singletonList(content));

        HttpEntity<Map<String, Object>> entity = new HttpEntity<>(requestBody, headers);

        try {
            ResponseEntity<String> response = restTemplate.postForEntity(aiApiUrl, entity, String.class);
            return response.getBody();
        } catch (Exception e) {
            throw new RuntimeException("调用Google AI API失败: " + e.getMessage(), e);
        }
    }

    /**
     * 【新增方法】: 使用AI将大段文本智能拆分成独立的题目列表
     * @param fullText 从Word文档中提取的全部文本
     * @return 包含多个题目字符串的JSON数组
     */
    public String splitTextIntoQuestions(String fullText) {
        String prompt = "你是一个文本处理专家。你的任务是将以下提供的、可能包含多道题目的长文本，拆分成一个JSON数组。数组中的每个元素都是一道独立的、完整的题目字符串。\n" +
                "请注意识别题目的起始标志，比如 '1.'、'2.'、'一、选择题' 等。\n\n" +
                "--- 待处理文本如下 ---\n" +
                fullText + "\n\n" +
                "--- 输出 ---\n" +
                "请直接返回JSON数组格式，不要包含任何其他说明文字。";

        return callAiApi(prompt);
    }


    /**
     * 【新】从文本中提取关键词作为标签
     * @param text 文档内容
     * @return 包含标签的JSON数组字符串
     */
    public String generateTags(String text) {
        String prompt = "你是一个信息提取AI。请从以下文本中提取5个最核心的关键词作为标签。请以JSON数组的格式返回，例如：[\"标签一\", \"标签二\"]。\n\n【文本内容】:\n" + text;
        return callAiApi(prompt);
    }

    /**
     * 【新】为文本生成一段简洁的摘要
     * @param text 文档内容
     * @return 包含摘要的JSON对象字符串
     */
    public String generateSummary(String text) {
        String prompt = "你是一个文本摘要AI。请为以下长文本生成一段不超过200字的简洁摘要。请以JSON对象的格式返回，例如：{\"summary\": \"这是摘要内容...\"}。\n\n【文本内容】:\n" + text;
        return callAiApi(prompt);
    }

    /**
     * 【新】从文本中提取关键知识点列表
     * @param text 文档内容
     * @return 包含知识点列表的JSON数组字符串
     */
    public String extractKnowledgePoints(String text) {
        String prompt = "你是一个教学分析AI。请从以下课程资料中，提炼出关键的知识点，并以JSON数组的格式返回一个列表，例如：[\"知识点一\", \"知识点二\"]。\n\n【文本内容】:\n" + text;
        return callAiApi(prompt);
    }

    /**
     * 【新】根据文本内容生成配套练习题
     * @param text 文档内容
     * @return 包含练习题的JSON数组字符串
     */
    public String generatePracticeQuestions(String text) {
        String prompt = "你是一个专业的出题AI。请根据以下学习资料，生成3道相关的练习题（一两道选择题，一道判断题）。你的返回结果必须是一个严格的JSON数组，每个问题对象都必须包含 'type'('multiple-choice' 或 'true-false'), 'question'(题干), 'options'(一个Map，仅对选择题存在), 'answer'(答案)。\n\n【学习资料】:\n" + text;
        return callAiApi(prompt);
    }
    /**
     * 【新】将文本转换为语义向量（Embeddings）
     * @param text 要转换的文本
     * @return 包含向量的JSON字符串
     */
    public String generateEmbeddings(String text) {
        // 注意：这里我们调用的是专门的 embedding 模型
        String embeddingApiUrl = "https://generativelanguage.googleapis.com/v1beta/models/text-embedding-004:embedContent?key=" + this.apiKey;

        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);

        // 构建请求体
        Map<String, Object> content = Map.of("parts", List.of(Map.of("text", text)));
        Map<String, Object> requestBody = Map.of("model", "models/text-embedding-004", "content", content);

        HttpEntity<Map<String, Object>> entity = new HttpEntity<>(requestBody, headers);

        try {
            // 使用共享的、带代理的RestTemplate实例
            return restTemplate.postForObject(embeddingApiUrl, entity, String.class);
        } catch (Exception e) {
            throw new RuntimeException("调用Google AI Embedding API失败: " + e.getMessage(), e);
        }
    }
    /**
     * 【新功能】: 根据虚拟学生性格、课堂内容和教师讲课的实时转录，生成互动聊天内容。
     * @param personality 学生性格，如 "积极提问型"
     * @param lessonContext 课堂主题
     * @param teacherTranscript 教师讲课的最新一小段文字记录
     * @return AI 生成的聊天内容，或在不需发言时返回空
     */
    public String generateVirtualStudentResponse(String personality, String lessonContext, String teacherTranscript) {
        String prompt = String.format(
                "你是一个在线教室里的虚拟学生。你的性格是“%s”。" +
                        "当前课堂主题是“%s”。" +
                        "老师刚刚讲了以下内容：“%s”。\n\n" +
                        "请根据你的性格，对老师的讲解做出简短、自然的互动回应。可以是提问、评论或感想。" +
                        "如果觉得此时不应发言，就返回一个空字符串。你的回应必须像一个真实的、正在打字的学生。" +
                        "【重要】不要说“好的，老师”等多余的话，直接输出你的问题或评论。",
                personality, lessonContext, teacherTranscript
        );

        // 复用已有的 callAiApi 方法
        String rawResponse = callAiApi(prompt);

        // 解析并提取AI的纯文本回复 (复用或创建一个解析方法)
        try {
            JsonNode rootNode = objectMapper.readTree(rawResponse);
            return rootNode.path("candidates").path(0).path("content").path("parts").path(0).path("text").asText("");
        } catch (Exception e) {
            // 在AI返回非标准格式时，返回空字符串
            return "";
        }
    }
}